package com.example.zhangwei.widgts;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Scroller;

public class MyCustomViewGroup extends ViewGroup{
	
	private Scroller mScroller;
		
	private int mCurScreen;
	
	private VelocityTracker mVelocityTracker;
	
	private float mLastMotionX;

    private float mLastMotionY;
      
    private static final int SNAP_VELOCITY = 600;

	private final static String TAG = "MyViewGroup";
	
	public MyCustomViewGroup(Context context) {
		super(context);
		Log.e(TAG, "--------------------------MyCustomViewGroup(Context context)");
		// TODO Auto-generated constructor stub
	}
	
	public MyCustomViewGroup(Context context, AttributeSet attrs) {
		super(context,attrs);//不写这个 在activity里面findbyid是找不到的
		
		mScroller = new Scroller(context);
		mCurScreen = 0;
		Log.e(TAG, "--------------------------MyCustomViewGroup(Context context, AttributeSet attrs)");
		// TODO Auto-generated constructor stub
	}
	
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		// TODO Auto-generated method stub
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		Log.e(TAG, "--------------------------onMeasure");
		Log.e(TAG, "widthMeasureSpec = "+widthMeasureSpec+" heightMeasureSpec"+heightMeasureSpec);
		
		final int width = MeasureSpec.getSize(widthMeasureSpec);
        final int widthMode = MeasureSpec.getMode(widthMeasureSpec);

        if (widthMode == MeasureSpec.UNSPECIFIED) 
        {
           throw new IllegalStateException("ScrollLayout can't run at UNSPECIFIED mode!");
        }
        
        @SuppressWarnings("unused")
		final int height = MeasureSpec.getSize(heightMeasureSpec);
        final int heightMode = MeasureSpec.getMode(heightMeasureSpec);

        if (heightMode == MeasureSpec.UNSPECIFIED) 
        {
            throw new IllegalStateException("ScrollLayout can't run at UNSPECIFIED mode!");
        }
        
		measureChildren(widthMeasureSpec, heightMeasureSpec);
		scrollTo(mCurScreen * width, 0);
	}

	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		// TODO Auto-generated method stub
		Log.e(TAG, "--------------------------onLayout");
		Log.e(TAG, "changed = "+changed+" left = "+l+" top = "+t+" right = "+r+" botom = "+b);
		int childLeft = 0;
		int count = getChildCount();
		for(int i=0;i<count;i++){
			final View child = this.getChildAt(i);
			if (child.getVisibility() != View.GONE) 
			{
				final int childWidth = child.getMeasuredWidth();
				child.layout(childLeft, t, childLeft + childWidth, child.getMeasuredHeight());
				childLeft += childWidth;
			}	
		}
	}
	
	@Override
	protected void onFinishInflate() {
		// TODO Auto-generated method stub
		Log.e(TAG, "--------------------------onFinishInflate");
		super.onFinishInflate();
	}
	
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		if (mVelocityTracker == null) 
		{
			mVelocityTracker = VelocityTracker.obtain();
		}
		mVelocityTracker.addMovement(event);
		final int action = event.getAction();
		final float x = event.getX();
		final float y = event.getY();

		//        Log.e(TAG, "onTouchEvent = " + event.getAction());
		switch (action) {
		case MotionEvent.ACTION_DOWN:
			Log.e(TAG, "event down!");
			if (!mScroller.isFinished()) 
			{
				mScroller.abortAnimation();
			}
			mLastMotionY = y;
			mLastMotionX = x;
			break;

		case MotionEvent.ACTION_MOVE:
			int deltaX = (int) (mLastMotionX - x);
			int deltaY = (int) (mLastMotionY - y);
			mLastMotionX = x;
			mLastMotionY = y;
			if (Math.abs(deltaX) > Math.abs(deltaY))
				scrollBy(deltaX, 0);
			break;

		case MotionEvent.ACTION_UP:

//			Log.e(TAG, "event : up");

			final VelocityTracker velocityTracker = mVelocityTracker;

			velocityTracker.computeCurrentVelocity(1000);

			int velocityX = (int) velocityTracker.getXVelocity();

//			Log.e(TAG, "velocityX:"+velocityX);

			if (velocityX > SNAP_VELOCITY && mCurScreen > 0) 
			{
//				Log.e(TAG, "snap left");

				snapToScreen(mCurScreen - 1);
			}
			else if (velocityX < -SNAP_VELOCITY && mCurScreen < getChildCount() - 1) 
			{
//				Log.e(TAG, "snap right");

				snapToScreen(mCurScreen + 1);
			} 
			else 
			{
				snapToDestination();
			}

			if (mVelocityTracker != null) 
			{
				mVelocityTracker.recycle();
				mVelocityTracker = null;
			}   	
			break;

		case MotionEvent.ACTION_CANCEL:
			break;

		}
		return true;
	}
	
	@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) {
		final int action = ev.getAction();
		final float x = ev.getX();
        final float y = ev.getY();
        switch (action) 
        {
        case MotionEvent.ACTION_MOVE:
        	mLastMotionY = y;
			mLastMotionX = x;
        	break;
        case MotionEvent.ACTION_DOWN:
        	int deltaX = (int) (mLastMotionX - x);
			int deltaY = (int) (mLastMotionY - y);
			mLastMotionX = x;
			mLastMotionY = y;
			if (Math.abs(deltaX) > Math.abs(deltaY))
			{
				return true;
			}	
        	break;
        case MotionEvent.ACTION_CANCEL:
        case MotionEvent.ACTION_UP:
        	break;
        }
		// TODO Auto-generated method stub
		return super.onInterceptTouchEvent(ev);
	}
	
	@Override
	public void computeScroll() {
		// TODO Auto-generated method stub
		super.computeScroll();
		
		if (mScroller.computeScrollOffset())
		{
            scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
            postInvalidate();
        }
	}
	
	private void snapToDestination() {
        final int screenWidth = getWidth();
        final int destScreen = (getScrollX() + screenWidth / 2) / screenWidth;
        snapToScreen(destScreen);
    }

	private void snapToScreen(int whichScreen) {
        whichScreen = Math.max(0, Math.min(whichScreen, getChildCount() - 1));
        if (getScrollX() != (whichScreen * getWidth())) 
        {
            final int delta = whichScreen * getWidth() - getScrollX();
            mScroller.startScroll(getScrollX(), getScrollY(),delta, getScrollY(), Math.abs(delta));
            mCurScreen = whichScreen;           
            invalidate();
        }
    }
    
    public void setToScreen(int whichScreen) 
    {
        whichScreen = Math.max(0, Math.min(whichScreen, getChildCount() - 1));
        mCurScreen = whichScreen;
        scrollTo(whichScreen * getWidth(), 0);
    }
    
    public void setToByScreen(int whichScreen) 
    {
    	snapToScreen(whichScreen);
    }

    public int getCurScreen() 
    {
        return mCurScreen;
    }

}
